<template>
    <div class="flex-container" :style="{ height: clientHeight + 'px' }">
        <div class="title">PDF转图片</div>
        <el-upload
            ref="upload"
            drag
            :limit="1"
            action="-"
            :auto-upload="false"
            accept=".pdf"
            :show-file-list="false"
            :on-change="onChange"
        >
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
        </el-upload>
        <el-button type="primary" @click="handleBack" size="medium" round style="margin-top: 25px">返回主页</el-button>
        <el-dialog
            title="密码"
            width="520px"
            :visible.sync="passVisible"
            :close-on-click-modal="false"
            @close="handleCancel"
        >
            <el-input v-model="password" clearable placeholder="请输入密码"></el-input>
            <div slot="footer" class="dialog-footer">
                <el-button @click.native="handleCancel">取消</el-button>
                <el-button type="primary" @click.native="handleData">确定</el-button>
            </div>
        </el-dialog>
    </div>
</template>

<script>
import * as pdfjsLib from 'pdfjs-dist/legacy/build/pdf.min.js'
pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdf.worker.min.js'
import JSZip from 'jszip'
import saveAs from 'file-saver'
export default {
    data() {
        return {
            clientHeight: document.documentElement.clientHeight || document.body.clientHeight,
            passVisible: false,
            password: '',
            url: '',
            load: null,
            filename: ''
        }
    },
    methods: {
        async handleData() {
            try {
                var zip = new JSZip()
                var loadTask = pdfjsLib.getDocument({ url: this.url, password: this.password })
                let that = this
                loadTask.onPassword = function passwordNeeded(updateCallback, reason) {
                    switch (reason) {
                        case 1:
                            that.passVisible = true
                            break
                        default:
                            that.$message.error('密码错误')
                            break
                    }
                }
                const pdf = await loadTask.promise
                this.load = this.$loading({
                    lock: true,
                    text: '正在导出...',
                    spinner: 'el-icon-loading',
                    background: 'rgba(0, 0, 0, 0.7)'
                })
                this.passVisible = false
                let numPages = pdf.numPages
                for (let i = 1; i <= numPages; i++) {
                    const image = await this.renderPdfPageAsImage(pdf, i)
                    const data = image.split(';base64,').pop()
                    zip.file(i + '.png', data, { base64: true })
                }
                zip.generateAsync({ type: 'blob' }).then(function (content) {
                    saveAs(content, that.filename + '.zip')
                })
            } catch (err) {
                if (err.name === 'PasswordException') {
                    this.passVisible = true
                } else {
                    console.error(err)
                }
            }
            this.load.close()
            URL.revokeObjectURL(this.url)
        },
        async renderPdfPageAsImage(pdf, pageNumber, scale = 1.67) {
            const page = await pdf.getPage(pageNumber)
            const viewport = page.getViewport({ scale: scale })
            const canvas = document.createElement('canvas')
            const context = canvas.getContext('2d')
            canvas.height = viewport.height
            canvas.width = viewport.width
            const renderContext = {
                canvasContext: context,
                viewport: viewport
            }
            await page.render(renderContext).promise
            return canvas.toDataURL('image/png')
        },
        onChange(file) {
            this.filename = file.name.split('.')[0]
            let pattern = /.(pdf)$/g
            if (!pattern.test(file.name)) {
                this.$message.error('只能上传pdf文件')
                return false
            }
            this.password = ''
            this.url = URL.createObjectURL(file.raw)
            this.handleData()
            this.$refs.upload.clearFiles()
            return true
        },
        handleBack() {
            this.$router.replace('/')
        },
        handleCancel() {
            this.passVisible = false
            URL.revokeObjectURL(this.url)
        }
    }
}
</script>

<style scoped>
.flex-container {
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
}
.el-button--primary {
    background-color: #505587;
    border-color: #505587;
}
.el-upload-dragger .el-upload__text em {
    color: #505587;
}
.title {
    font-size: 24px;
    line-height: 34px;
    color: #33333b;
    font-weight: 600;
    margin-bottom: 25px;
}
</style>
